package com.example.demo.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.example.demo.AppUtil.ApiPageUtils;
import com.example.demo.AppUtil.BaseActionUtil;
import com.example.demo.AppUtil.Query;
import com.example.demo.anno.LoginUser;
import com.example.demo.config.OssConfig;
import com.example.demo.entity.*;
import com.example.demo.entity.DTO.GoodsDTO;
import com.example.demo.entity.DTO.GoodsNewDTO;
import com.example.demo.entity.VO.GoodsAddVO;
import com.example.demo.entity.VO.GoodsBookedVO;
import com.example.demo.entity.VO.GoodsVO;
import com.example.demo.result.Result;
import com.example.demo.service.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.qiniu.util.StringUtils;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;

/**
 * <p>
 * 商品表 前端控制器
 * </p>
 *
 * @author Mr.Xiayh
 * @since 2024-06-04
 */
@Api(tags = "商品接口")
@Slf4j
@RestController
@RequestMapping("/goods")
public class GoodsController extends BaseActionUtil {

    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IGoodsBookedService goodsBookedService;
    @Autowired
    private IGoodsImgService goodsImgService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private OssConfig ossConfig;
    @Autowired
    private IAnNideshopGoodService anNideshopGoodService;
    @Autowired
    private IAfoneshopAdService afoneshopAdService;
    @Autowired
    private IAfoneshopTopicService afoneshopTopicService;
    @Autowired
    private IAfoneCategoryService categoryService;
    @Autowired
    private IAfshopSearchHistoryService afshopSearchHistoryService;

    @ApiOperation(value = "获取商品列表")
    @PostMapping("/list")
    @ApiOperationSupport(author = "Mr.力铉器")
    @ApiImplicitParams({@ApiImplicitParam(name = "categoryId", value = "分类id", paramType = "path", required = true),
            @ApiImplicitParam(name = "brandId", value = "品牌Id", paramType = "path", required = true),
            @ApiImplicitParam(name = "isNew", value = "新商品", paramType = "path", required = true),
            @ApiImplicitParam(name = "isHot", value = "热卖商品", paramType = "path", required = true)})
    public Object list(@LoginUser User loginUser, Integer categoryId,
                       Integer brandId, String keyword, Integer isNew, Integer isHot,
                       @RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "size", defaultValue = "10") Integer size,
                       String sort, String order) {
        Map<String, Object> params = new HashMap<>();
        params.put("isDelete", 0);
        params.put("isOnSale", 1);
        params.put("brandId", brandId);
        params.put("keyword", keyword);
        params.put("isNew", isNew);
        params.put("isHot", isHot);
        params.put("page", page);
        params.put("limit", size);
        params.put("order", sort);
        params.put("sidx", order);
        //
        if (null != sort && "price".equals(sort)) {
            params.put("sidx", "retail_price");
            params.put("order", order);
        } else {
            params.put("sidx", "id");
            params.put("order", "desc");
        }
        //添加到搜索历史
        if (!StringUtils.isNullOrEmpty(keyword)) {
            AfshopSearchHistory searchHistoryVo = new AfshopSearchHistory();
            searchHistoryVo.setAddTime(System.currentTimeMillis() / 1000);
            searchHistoryVo.setKeyword(keyword);
            searchHistoryVo.setUserId(null != loginUser ? loginUser.getUserId().toString() : "");
            searchHistoryVo.setFrom("");
            afshopSearchHistoryService.save(searchHistoryVo);

        }
        //筛选的分类
        List<AfoneCategory> filterCategory = new ArrayList<>();
        AfoneCategory rootCategory = new AfoneCategory();
        rootCategory.setId(0);
        rootCategory.setName("全部");
        rootCategory.setChecked(false);
        filterCategory.add(rootCategory);
        //
        params.put("fields", "category_id");
        List<GoodsNewDTO> categoryEntityList = goodsService.queryList(params);
        params.remove("fields");
        if (null != categoryEntityList && !categoryEntityList.isEmpty()) {
            List<Integer> categoryIds = new ArrayList<>();
            for (AnNideshopGood goodsVo : categoryEntityList) {
                categoryIds.add(goodsVo.getCategoryId());
            }
            //查找二级分类的parentId
            Map<String, Object> categoryParam = new HashMap<>();
            categoryParam.put("ids", categoryIds);
            categoryParam.put("fields", "parent_id");
            List<AfoneCategory> parentCategoryList = categoryService.queryList(categoryParam);
            //
            List<Integer> parentIds = new ArrayList<>();
            for (AfoneCategory categoryEntity : parentCategoryList) {
                parentIds.add(categoryEntity.getParentId());
            }
            //一级分类
            categoryParam = new HashMap<>();
            categoryParam.put("fields", "id,name");
            categoryParam.put("order", "asc");
            categoryParam.put("sidx", "sort_order");
            categoryParam.put("ids", parentIds);
            List<AfoneCategory> parentCategory = categoryService.queryList(categoryParam);
            if (null != parentCategory) {
                filterCategory.addAll(parentCategory);
            }
        }
        //加入分类条件
        if (null != categoryId && categoryId > 0) {
            List<Integer> categoryIds = new ArrayList<>();
            Map<String, Object> categoryParam = new HashMap<>();
            categoryParam.put("parentId", categoryId);
            categoryParam.put("fields", "id");
            List<AfoneCategory> childIds = categoryService.queryList(categoryParam);
            for (AfoneCategory categoryEntity : childIds) {
                categoryIds.add(categoryEntity.getId());
            }
            categoryIds.add(categoryId);
            params.put("categoryIds", categoryIds);
        }
        //查询列表数据
        params.put("fields", "id, name, list_pic_url, market_price, retail_price, goods_brief");
        Query query = new Query(params);
        PageHelper.startPage(query.getPage(), query.getLimit());
        List<GoodsNewDTO> goodsList = goodsService.queryList(query);
        ApiPageUtils goodsData = new ApiPageUtils(new PageInfo(goodsList));
        //搜索到的商品
        for (AfoneCategory categoryEntity : filterCategory) {
            if (null != categoryId && (categoryEntity.getId() == 0 || categoryId.equals(categoryEntity.getId()))
                    ||null == categoryId&&null == categoryEntity.getId()) {
                categoryEntity.setChecked(true);
            } else {
                categoryEntity.setChecked(false);
            }
        }
        goodsData.setFilterCategory(filterCategory);
        goodsData.setGoodsList(goodsList);
        return toResponseSuccess(goodsData);
    }

    @ApiOperation(value = " 获取分类下的商品数据")
    @PostMapping("/category")
    @ApiOperationSupport(author = "Mr.力铉器")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "分类id", paramType = "path", required = true)})
    public Object category(Integer id) {
        Map<String, Object> resultObj = new HashMap<>();
        //
        AfoneCategory currentCategory = categoryService.queryObject(id);
        //
        AfoneCategory parentCategory = categoryService.queryObject(currentCategory.getParentId());
        Map<String, Object> params = new HashMap<>();
        params.put("parentId", currentCategory.getParentId());
        List<AfoneCategory> brotherCategory = categoryService.queryList(params);
        //
        resultObj.put("currentCategory", currentCategory);
        resultObj.put("parentCategory", parentCategory);
        resultObj.put("brotherCategory", brotherCategory);
        return toResponseSuccess(resultObj);
    }

    @ApiOperationSupport(author = "Mr.力铉器")
    @ApiOperation(value = "在售的商品总数")
    @PostMapping("/count")
    public Object count() {
        Map<String, Object> resultObj = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        param.put("isDelete", 0);
        param.put("isOnSale", 1);
        Integer goodsCount = goodsService.queryTotal(param);
        resultObj.put("goodsCount", goodsCount);
        return toResponseSuccess(resultObj);
    }

    @ApiOperationSupport(author = "Mr.力铉器")
    @ApiOperation(value = "热卖商品")
    @PostMapping("/hostGoods")
    public Object hostGoods() {

        // 初始化一个结果对象映射，用于存储最终返回的数据
        Map<String, Object> resultObj = new HashMap<>();

        // 初始化参数映射，用于传递查询热门商品的条件
        Map<String, Object> param = new HashMap<>();

        // 设置参数映射中的条件：商品是否热门，这里设定为热门（1表示热门）
        param.put("isHot", "1");

        // 设置参数映射中的条件：商品是否被删除，这里设定为未删除（0表示未删除）
        param.put("isDelete", 0);

        // 调用服务层方法，根据参数查询热门商品列表
        List<GoodsNewDTO> hotGoods = anNideshopGoodService.queryHotGoodsList(param);

        // 将查询到的热门商品列表存储到结果对象映射中，以"hotGoodsList"为键
        resultObj.put("hotGoodsList", hotGoods);

        return toResponseSuccess(resultObj);
    }
    @ApiOperationSupport(author = "Mr.力铉器")
    @ApiOperation(value = "新品首发")
    @PostMapping("/new")
    public Object newGoods() {
        Map<String, Object> resultObj = new HashMap<>();
        Map<String, Object> bannerInfo = new HashMap<>();
        bannerInfo.put("url", "");
        bannerInfo.put("name", "坚持初心，为你寻觅世间好物");
        bannerInfo.put("imgUrl", "https://platform-wxmall.oss-cn-beijing.aliyuncs.com/upload/20180727/1504208321fef4.png");
        resultObj.put("bannerInfo", bannerInfo);
        return toResponseSuccess(resultObj);
    }
    @ApiOperationSupport(author = "Mr.力铉器")
    @ApiOperation(value = "商品首页")
    @PostMapping("/index")
    public Object index() {
        Map<String, Object> resultObj = new HashMap<String, Object>();

        // 初始化参数映射，用于存储查询广告位的条件
        Map<String, Object> param = new HashMap<String, Object>();

        // 设置查询条件：广告位ID为1
        param.put("ad_position_id", 1);

        // 调用广告服务的查询方法，获取广告列表
        List<AfoneshopAd> banner = afoneshopAdService.queryList(param);

        // 将广告列表存储到结果对象中，作为"banner"属性
        resultObj.put("banner", banner);

        return toResponseSuccess(resultObj);
    }
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "添加商品信息")
    @PostMapping("/add")
    public Result<String> add(@Valid @RequestBody GoodsAddVO goodsAddVO) {
       Goods goods = new Goods();
        BeanUtil.copyProperties(goodsAddVO, goods);
        boolean isGoodsAdded = goodsService.addGoods(goods);

        if (!isGoodsAdded) {
            return Result.error().msg("添加失败");
        }
        // 如果有图片需要添加
        if (goodsAddVO.getGoodsImg() != null) {
            boolean isImgAdded = goodsImgService.addGoodsImg(goods.getGoodsId(),goodsAddVO.getGoodsImg());
            if (!isImgAdded) {
                return Result.error().msg("图片添加失败");
            }
        }
        return Result.success().msg("添加成功");
    }

    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "添加商品图片")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "goodsId", value = "商品id",required = true),
            @ApiImplicitParam(name = "path", value = "图片路径(传入:传入图片返回的路径)",required = true)
    })
    @PostMapping("/addImg")
    public Result<String> addImg(@RequestParam Integer goodsId,@RequestParam List<String> path) {
        if (goodsService.getById(goodsId) == null) {
            return Result.error().msg("商品不存在");
        }
        boolean isImgAdded = goodsImgService.addGoodsImg(goodsId,path);
        if (!isImgAdded) {
            return Result.error().msg("图片添加失败");
        }
        return Result.success().msg("图片添加成功");
    }

    /**
     * 根据内容查找所有接口
     *
     * @return
     */
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "查找所有商品(传什么参数就以什么查 可传null)")
    @PostMapping("/findAllByCriteria")
    public Result<List<GoodsDTO>> findAllByCriteria(@RequestBody(required = false) GoodsVO goodsVO) {
        // 创建一个Goods对象，并使用BeanUtil将goodsVO中的属性复制到Goods对象中。
        Goods goods = new Goods();
        // 使用BeanUtil将goodsVO中的属性复制到Goods对象中
        BeanUtil.copyProperties(goodsVO, goods);
        return Result.success().msg("查询成功").data(goodsService.findAllByCriteria(goods));
    }

    /**
     * 根据内容查找所有接口
     *
     * @return
     */
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "随机推送商品接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "num", value = "返回随机数", required = true)
    })
    @PostMapping("/randomGoods")
    public Result<List<GoodsDTO>> randomGoods(@RequestParam Integer num) {
        // 查询所有商品信息
        List<GoodsDTO> allByCriteria = goodsService.findAllByCriteria(null);

        // 打乱列表中的元素顺序，以确保后续选取的元素是随机的。
        Collections.shuffle(allByCriteria);

        // 截取列表的前num个元素
        allByCriteria = allByCriteria.subList(0, num);


        return Result.success().msg("查询成功").data(allByCriteria);
    }

    /**
     * 根据内容查找所有接口
     *
     * @return
     */
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "商品预约接口")
    @PostMapping("/bookedGoods")
    public Result<List<GoodsDTO>> bookedGoods(@Valid @RequestBody GoodsBookedVO goodsBookedVO) {
        // 实例化实体类,方便存入
        GoodsBooked goodsBooked = new GoodsBooked();
        // 将VO转换为实体类 方便数据库操作
        BeanUtil.copyProperties(goodsBookedVO, goodsBooked);
        // 设置创建时间
        goodsBooked.setCreateTime(LocalDateTimeUtil.now());
        // 调用业务层方法
        if (!goodsBookedService.saveGoodsBooked(goodsBooked)) {
            // 预约失败
            return Result.error().msg("预约失败").code(10002);
        }
        // 成功
        return Result.success().msg("预约成功");
    }

    /**
     *
     * @param name
     * @return
     */
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "商品搜索栏专用接口")
    @GetMapping("/findGoods")
    public Result<List<GoodsDTO>> findGoods(@RequestParam String name,@RequestParam Integer userId) {
        // TODO 用户id从Token内获取
        Goods goods = new Goods();
        goods.setGoodsName(name);
        // 调用查找接口
        List<GoodsDTO> allByCriteria = goodsService.findAllByCriteria(goods);
        // 将用户ID和搜索条件传入Redis
        redisTemplate.opsForHash().put(String.valueOf(userId),name,String.valueOf(System.currentTimeMillis()));
        // 返回结果
        return Result.success().msg("查询成功").data(allByCriteria);
    }

    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "历史搜索查询接口")
    @GetMapping("/historySearch")
    public Result<List<GoodsDTO>> historySearch(@RequestParam Integer userId) {
        // TODO 用户id从Token内获取
        // 从redis中查询数据Hash的Field
        List<Object> values = redisTemplate.opsForHash().values(String.valueOf(userId));
        for (Object value : values) {
            // key是时间戳 检查key的时间戳和现在的时间 > 30天
            if (System.currentTimeMillis() - Long.parseLong(value.toString()) > 30 * 24 * 60 * 60 * 1000) {
                // 删除redis中的数据
                redisTemplate.opsForHash().delete(String.valueOf(userId),value);
            }

        }
        Set<Object> keys = redisTemplate.opsForHash().keys(String.valueOf(userId));
        // 将取到的值返回前端
        return Result.success().msg("查询成功").data(keys);
    }


    /**
     * 根据id查询数据接口
     * @param id
     * @return
     *//*
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "根据id查询数据接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "组件id",required = true)
    })
    @GetMapping("/{id}")
    public Result<Goods> findOne(@PathVariable Integer id) {
        return Result.success(goodsService.getById(id)).msg("查询成功");
    }*/

    /* *//**
     * 分页查询接口
     * @param pageNum
     * @param pageSize
     * @return
     *//*
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "分页查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum",value = "页码",example="1",required = true),
            @ApiImplicitParam(name = "pageSize",value = "每页多少条",example="10",required = true)
    })
    @GetMapping("/page")
    public Result<MyPage<Goods>> findPage(@RequestParam Integer pageNum,@RequestParam Integer pageSize) {
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        return Result.success().data(goodsService.page(new Page<>(pageNum, pageSize), queryWrapper)).msg("查询成功");
    }*/

    /**
     * 新增
     * @param
     * @return
     *//*
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "新增")
    @PostMapping("/add")
    //TODO 记得来创建这个VO
    public Result<String> add() {
        //TODO VO转Entity
        //goodsService.saveOrUpdate(goods);
        return Result.success().msg("添加成功");
    }*/

    /* *//**
     * 更新接口
     * @param
     * @return
     *//*
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "更新接口")
    @PutMapping
    public Result<String> save(@RequestBody Goods goods) {
        goodsService.saveOrUpdate(goods);
        return Result.success().msg("更新成功");
    }*/

    /**
     * 删除接口
     * @param id
     * @return
     *//*
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "删除接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "组件id",required = true)
    })
    @DeleteMapping("/{id}")
    public Result<String> delete(@PathVariable Integer id) {
        goodsService.removeById(id);
        return Result.success().msg("删除成功");
    }*/

    /**
     * 批量删除接口
     * @param ids
     * @return
     *//*
    @ApiOperationSupport(author = "Mr.Xiayh")
    @ApiOperation(value = "批量删除接口")
    @PostMapping("/del/batch")
    public Result<String> deleteBatch(@RequestBody List<Integer> ids) {
        goodsService.removeByIds(ids);
        return Result.success().msg("批量删除成功");
    }*/
}